/*******************************************************************************
** Copyright (c) 2004 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/

#pragma warning(disable: 4251)
#pragma warning(disable: 4786)
#pragma warning(disable: 4290)

#include <iostream>
#include "fedAmb1516.h"
#include "stringUtil.h"

#include "PDAServer.h"
//extern pdasrv server;
using namespace std;

void printAttrValues(AttributeHandleValueMap const& attrVals)
{
   AttributeHandleValueMap::const_iterator iter;

   for (iter = attrVals.begin(); iter != attrVals.end(); iter++)
   {
      wcout << iter->first.toString().c_str() << L" "
            << DtToWString((char*)iter->second.data()).c_str() << endl;
   }
}

void printParamValues(ParameterHandleValueMap const& paramVals)
{
   ParameterHandleValueMap::const_iterator iter;

   for (iter = paramVals.begin(); iter != paramVals.end(); iter++)
   {
      wcout << iter->first.toString().c_str() << L" "
            << DtToWString((char*)iter->second.data()).c_str() << endl;
   }
}

MyFederateAmbassador::MyFederateAmbassador(DtTalkAmbData & data) :
   NullFederateAmbassador(), myData(data) {}

MyFederateAmbassador::~MyFederateAmbassador()
   throw () {}


void
MyFederateAmbassador::objectInstanceNameReservationSucceeded(
   std::wstring const & theObjectInstanceName)
   throw (
      UnknownName,
      FederateInternalError)
{
//	server.transmit(L"objectInstanceNameReservationSucceeded");
   wcout << L"objectInstanceNameReservationSucceeded: "
         << theObjectInstanceName.c_str() << endl;
   myData.myNameReservationReturned = 
   myData.myNameReservationSucceeded = true;
}

void MyFederateAmbassador::objectInstanceNameReservationFailed(
   std::wstring const & theObjectInstanceName)
   throw (
      UnknownName,
      FederateInternalError)
{
   wcout << L"objectInstanceNameReservationFailed: "
         << theObjectInstanceName.c_str() << endl;
   myData.myNameReservationReturned = true;
   myData.myNameReservationSucceeded = false;
}

void MyFederateAmbassador::discoverObjectInstance (
   ObjectInstanceHandle theObject,
   ObjectClassHandle theObjectClass,
   std::wstring const & theObjectInstanceName)
   throw (
      CouldNotDiscover,
      ObjectClassNotKnown,
      FederateInternalError)
{
//	server.transmit(L"discoverObjectInstance");
   wcout << L"discoverObjectInstance: "
         << theObjectInstanceName.c_str() << L"("
         << theObject.toString().c_str() << L") of class "
         << myData.objectClassMap[theObjectClass].c_str() << L"( "
         << theObjectClass.toString().c_str() << L")" << endl;\
   myData.objectInstanceMap[theObject] = theObjectInstanceName;

   server::PDAServer::getInstance()->sendCallback(new Callback(DISCOVER_OBJECT_INSTANCE, theObjectInstanceName.c_str()));
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      FederateInternalError)
{
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";
//server.transmit(L"reflectAttributeValues");
   wcout << L"reflectAttributeValues h v u o p: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
   server::PDAServer::getInstance()->sendCallback(new Callback(REFLECT_ATTRIBUTE_VALUES, myData.objectInstanceMap[theObject].c_str()));
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      FederateInternalError)
{//server.transmit(L"reflectAttributeValues");
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"reflectAttributeValues h v u o p r: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      FederateInternalError)
{//server.transmit(L"reflectAttributeValues");
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"reflectAttributeValues h v u o p t o: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      FederateInternalError)
{//server.transmit(L"reflectAttributeValues");
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"reflectAttributeValues h v u o p t o r: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      InvalidLogicalTime,
      FederateInternalError)
{//server.transmit(L"reflectAttributeValues");
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"reflectAttributeValues h v u o p t o m: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theHandle.toString().c_str() << L" "
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      InvalidLogicalTime,
      FederateInternalError)
{//server.transmit(L"reflectAttributeValues");
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"reflectAttributeValues h v u o p t o m r: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString().c_str() << L" "
         << theHandle.toString().c_str() << L" "
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#attributes: " << theAttributeValues.size() << endl;

   printAttrValues(theAttributeValues);
}


// 6.9
void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}


void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}




void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}




void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}




void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          InvalidLogicalTime,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theHandle.toString() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}




void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          InvalidLogicalTime,
          FederateInternalError) {}


void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder)
   throw (
      ObjectInstanceNotKnown,
      FederateInternalError)
{
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ") << endl;
}

void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   LogicalTime const & theTime,
   OrderType receivedOrder)
   throw (
      ObjectInstanceNotKnown,
      FederateInternalError)
{
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ") << endl;
}

 void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle)
   throw (
      ObjectInstanceNotKnown,
      InvalidLogicalTime,
      FederateInternalError)
 {
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theHandle.toString().c_str()  << endl;
}



